<template>
  <el-card>
    <div class="page-header">
      <!-- 将操作按钮区域移到顶部右侧 -->
      <div class="top-action-buttons">
        <el-button type="primary" @click="submitForm">保存</el-button>
        <el-button type="success" @click="handleGenCode">生成前后端代码</el-button>
        <el-dropdown split-button type="danger" @click="handleDeleteCode" @command="handleDeleteCommand">
          删除生成代码
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="frontend">删除前端代码</el-dropdown-item>
            <el-dropdown-item command="backend">删除后端代码</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </div>
      <el-tabs v-model="activeName" class="tabs-container custom-tabs">
        <el-tab-pane label="字段信息" name="columnInfo">
          <div slot="label">
            <div class="custom-tab-label">
              <i class="el-icon-tickets"></i>
              <span>字段信息</span>
            </div>
          </div>
          <el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight">
            <el-table-column label="序号" type="index" min-width="5%" class-name="allowDrag" />
            <el-table-column
              label="字段列名"
              prop="columnName"
              min-width="10%"
              :show-overflow-tooltip="true"
            />
            <el-table-column label="字段描述" min-width="10%">
              <template slot-scope="scope">
                <el-input v-model="scope.row.columnComment"></el-input>
              </template>
            </el-table-column>
            <el-table-column
              label="物理类型"
              prop="columnType"
              min-width="10%"
              :show-overflow-tooltip="true"
            />
            <el-table-column label="Java类型" min-width="11%">
              <template slot-scope="scope">
                <el-select v-model="scope.row.javaType">
                  <el-option label="Long" value="Long" />
                  <el-option label="String" value="String" />
                  <el-option label="Integer" value="Integer" />
                  <el-option label="Double" value="Double" />
                  <el-option label="BigDecimal" value="BigDecimal" />
                  <el-option label="Date" value="Date" />
                  <el-option label="Boolean" value="Boolean" />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column label="java属性" min-width="10%">
              <template slot-scope="scope">
                <el-input v-model="scope.row.javaField"></el-input>
              </template>
            </el-table-column>

            <el-table-column label="插入" min-width="5%">
              <template slot-scope="scope">
                <el-checkbox true-label="1" false-label="0" v-model="scope.row.isInsert"></el-checkbox>
              </template>
            </el-table-column>
            <el-table-column label="编辑" min-width="5%">
              <template slot-scope="scope">
                <el-checkbox true-label="1" false-label="0" v-model="scope.row.isEdit"></el-checkbox>
              </template>
            </el-table-column>
            <el-table-column label="列表" min-width="5%">
              <template slot-scope="scope">
                <el-checkbox true-label="1" false-label="0" v-model="scope.row.isList"></el-checkbox>
              </template>
            </el-table-column>
            <el-table-column label="查询" min-width="5%">
              <template slot-scope="scope">
                <el-checkbox true-label="1" false-label="0" v-model="scope.row.isQuery"></el-checkbox>
              </template>
            </el-table-column>
            <el-table-column label="查询方式" min-width="10%">
              <template slot-scope="scope">
                <el-select v-model="scope.row.queryType">
                  <el-option label="=" value="EQ" />
                  <el-option label="!=" value="NE" />
                  <el-option label=">" value="GT" />
                  <el-option label=">=" value="GTE" />
                  <el-option label="<" value="LT" />
                  <el-option label="<=" value="LTE" />
                  <el-option label="LIKE" value="LIKE" />
                  <el-option label="BETWEEN" value="BETWEEN" />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column label="必填" min-width="5%">
              <template slot-scope="scope">
                <el-checkbox true-label="1" false-label="0" v-model="scope.row.isRequired"></el-checkbox>
              </template>
            </el-table-column>
            <el-table-column label="显示类型" min-width="12%">
              <template slot-scope="scope">
                <el-select v-model="scope.row.htmlType">
                  <el-option label="文本框" value="input" />
                  <el-option label="文本域" value="textarea" />
                  <el-option label="下拉框" value="select" />
                  <el-option label="单选框" value="radio" />
                  <el-option label="复选框" value="checkbox" />
                  <el-option label="日期控件" value="datetime" />
                  <el-option label="图片上传" value="imageUpload" />
                  <el-option label="文件上传" value="fileUpload" />
                  <el-option label="富文本控件" value="editor" />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column label="字典类型" min-width="12%">
              <template slot-scope="scope">
                <el-select v-model="scope.row.dictType" clearable filterable placeholder="请选择">
                  <el-option
                    v-for="dict in dictOptions"
                    :key="dict.dictType"
                    :label="dict.dictName"
                    :value="dict.dictType">
                    <span style="float: left">{{ dict.dictName }}</span>
                    <span style="float: right; color: #8492a6; font-size: 13px">{{ dict.dictType }}</span>
                </el-option>
                </el-select>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        <el-tab-pane label="生成信息" name="genInfo">
          <div slot="label">
            <div class="custom-tab-label">
              <i class="el-icon-setting"></i>
              <span>生成信息</span>
            </div>
          </div>
          <gen-info-form ref="genInfo" :info="info" :tables="tables" :menus="menus" @preview-data="handlePreviewData"/>
        </el-tab-pane>
      </el-tabs>
    </div>

    <!-- 预览代码 -->
    <el-dialog 
      :title="preview.title" 
      :visible.sync="preview.open" 
      width="90%" 
      top="3vh" 
      append-to-body 
      class="scrollbar preview-dialog"
      :close-on-click-modal="false"
      :before-close="handleClosePreview">
      <el-tabs v-model="previewTabType" type="card">
        <el-tab-pane label="表结构SQL" name="tableStructure">
          <div class="preview-header">
            <div class="preview-actions">
              <el-button 
                type="primary" 
                size="small" 
                icon="el-icon-document-copy" 
                v-clipboard:copy="tableSqlContent" 
                v-clipboard:success="clipboardSuccess">
                复制SQL
              </el-button>
            </div>
          </div>
          <div class="preview-content">
            <pre v-if="tableSqlContent">
              <code class="hljs code-block" v-html="highlightedCode(tableSqlContent, 'sql')"></code>
            </pre>
            <div v-else class="empty-data">
              <i class="el-icon-loading"></i>
              <p>正在加载表结构SQL...</p>
            </div>
          </div>
        </el-tab-pane>
        
        <el-tab-pane label="后端代码" name="backend">
          <div v-if="backendCodeFiles.length > 0">
            <div class="preview-header">
              <div class="file-tabs">
                <div
                  v-for="(item, index) in backendCodeFiles"
                  :key="index"
                  :class="['file-tab', {'active': preview.activeName === index.toString()}]"
                  @click="preview.activeName = index.toString()">
                  {{ item.title }}
                </div>
              </div>
              <div class="preview-actions">
                <el-button 
                  type="primary" 
                  size="small" 
                  icon="el-icon-document-copy" 
                  v-clipboard:copy="getCurrentBackendCode" 
                  v-clipboard:success="clipboardSuccess">
                  复制代码
                </el-button>
              </div>
            </div>
            <div class="preview-content">
              <pre v-for="(item, index) in backendCodeFiles" 
                   :key="index" 
                   v-show="preview.activeName === index.toString()">
                <code class="hljs code-block" v-html="highlightedCode(item.content, item.title)"></code>
              </pre>
            </div>
          </div>
          <div v-else class="empty-data">
            <i class="el-icon-document"></i>
            <p>没有可用的后端代码</p>
          </div>
        </el-tab-pane>
        
        <el-tab-pane label="前端代码" name="frontend">
          <div v-if="frontendCodeFiles.length > 0">
            <div class="preview-header">
              <div class="file-tabs">
                <div
                  v-for="(item, index) in frontendCodeFiles"
                  :key="index"
                  :class="['file-tab', {'active': previewFrontend.activeName === index.toString()}]"
                  @click="previewFrontend.activeName = index.toString()">
                  {{ item.title }}
                </div>
              </div>
              <div class="preview-actions">
                <el-button 
                  type="primary" 
                  size="small" 
                  icon="el-icon-document-copy" 
                  v-clipboard:copy="getCurrentFrontendCode" 
                  v-clipboard:success="clipboardSuccess">
                  复制代码
                </el-button>
              </div>
            </div>
            <div class="preview-content">
              <pre v-for="(item, index) in frontendCodeFiles" 
                   :key="index" 
                   v-show="previewFrontend.activeName === index.toString()">
                <code class="hljs code-block" v-html="highlightedCode(item.content, item.title)"></code>
              </pre>
            </div>
          </div>
          <div v-else class="empty-data">
            <i class="el-icon-document"></i>
            <p>没有可用的前端代码</p>
          </div>
        </el-tab-pane>
        
        <el-tab-pane label="配置SQL" name="sql">
          <div v-if="sqlFiles.length > 0">
            <div class="preview-header">
              <div class="file-tabs">
                <div
                  v-for="(item, index) in sqlFiles"
                  :key="index"
                  :class="['file-tab', {'active': previewSql.activeName === index.toString()}]"
                  @click="previewSql.activeName = index.toString()">
                  {{ item.title }}
                </div>
              </div>
              <div class="preview-actions">
                <el-button 
                  type="primary" 
                  size="small" 
                  icon="el-icon-document-copy" 
                  v-clipboard:copy="getCurrentSqlCode" 
                  v-clipboard:success="clipboardSuccess">
                  复制代码
                </el-button>
              </div>
            </div>
            <div class="preview-content">
              <pre v-for="(item, index) in sqlFiles" 
                   :key="index" 
                   v-show="previewSql.activeName === index.toString()">
                <code class="hljs code-block" v-html="highlightedCode(item.content, item.title)"></code>
              </pre>
            </div>
          </div>
          <div v-else class="empty-data">
            <i class="el-icon-document"></i>
            <p>没有可用的SQL配置</p>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-dialog>

    <!-- 生成结果对话框 -->
    <el-dialog :title="genType === '1' ? '代码生成结果' : '代码生成'" :visible.sync="genResultVisible" width="500px" append-to-body>
      <div v-if="genSuccessful">
        <el-alert
          type="success"
          title="代码生成成功"
          description="代码已生成到指定路径"
          show-icon
          :closable="false">
        </el-alert>
        <div v-if="genType === '1'" style="margin-top: 15px">
          <p>生成路径: <el-tag type="primary">{{ genPath || '/' }}</el-tag></p>
          <p v-if="backendGenPath">后端代码: <el-tag type="success">{{ backendGenPath || genPath || '/' }}</el-tag></p>
          <p v-if="frontendGenPath">前端代码: <el-tag type="warning">{{ frontendGenPath || genPath || '/' }}</el-tag></p>
          
          <!-- 添加提示信息 -->
          <div v-if="genErrorMsg" style="margin-top: 10px">
            <el-alert
              type="warning"
              :title="genErrorMsg"
              show-icon>
            </el-alert>
          </div>
        </div>
      </div>
      <div v-else>
        <el-alert
          type="error"
          :title="'代码生成失败'"
          :description="genErrorMsg || '生成过程中发生错误，请重试或联系管理员'"
          show-icon
          :closable="false">
        </el-alert>
      </div>
      <div slot="footer">
        <el-button @click="genResultVisible = false">关闭</el-button>
      </div>
    </el-dialog>

    <!-- 表结构SQL对话框 -->
    <el-dialog title="表结构SQL" :visible.sync="tableSqlVisible" width="80%" top="5vh" append-to-body class="scrollbar">
      <pre><code class="hljs" v-html="highlightedCode(tableSqlContent, 'sql')"></code></pre>
      <div slot="footer">
        <el-button type="primary" size="small" icon="el-icon-document-copy" v-clipboard:copy="tableSqlContent" v-clipboard:success="clipboardSuccess">复制SQL</el-button>
        <el-button @click="tableSqlVisible = false">关闭</el-button>
      </div>
    </el-dialog>
  </el-card>
</template>

<script>
import { getGenTable, updateGenTable, genCode, previewTable, getWorkspace, deleteCode, checkFileExists, deleteFrontendCode, deleteBackendCode, getTableSql } from "@/api/tool/gen";
import { optionselect as getDictOptionselect } from "@/api/system/dict/type";
import { listMenu as getMenuTreeselect } from "@/api/system/menu";
import genInfoForm from "./genInfoForm";
import Sortable from 'sortablejs'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
import _ from 'lodash'

export default {
  name: "GenEdit",
  components: {
    genInfoForm
  },
  data() {
    return {
      // 选中选项卡的 name
      activeName: "columnInfo",
      // 表格的高度
      tableHeight: document.documentElement.scrollHeight - 245 + "px",
      // 表信息
      tables: [],
      // 表列信息
      columns: [],
      // 字典信息
      dictOptions: [],
      // 菜单信息
      menus: [],
      // 表详细信息
      info: {},
      genResultVisible: false,
      genSuccessful: false,
      genType: '',
      backendGenPath: '',
      frontendGenPath: '',
      genPath: '',
      genErrorMsg: '',
      deleteSuccessful: false,
      deleteResultVisible: false,
      preview: {
        title: '',
        open: false,
        data: [],
        activeName: '0'
      },
      previewTabType: 'backend',
      previewFrontend: {
        activeName: '0'
      },
      previewSql: {
        activeName: '0'
      },
      backendCodeFiles: [],
      frontendCodeFiles: [],
      sqlFiles: [],
      // 表结构SQL对话框
      tableSqlVisible: false,
      tableSqlContent: ""
    };
  },
  computed: {
    // 获取表ID
    tableId() {
      return this.info && this.info.tableId ? this.info.tableId : null;
    },
    getCurrentCode() {
      if (!this.preview.data || this.preview.data.length === 0) {
        return '';
      }
      const index = parseInt(this.preview.activeName || '0');
      return this.preview.data[index] ? this.preview.data[index].content : '';
    },
    getCurrentBackendCode() {
      if (!this.backendCodeFiles || this.backendCodeFiles.length === 0) {
        return '';
      }
      const index = parseInt(this.preview.activeName || '0');
      return this.backendCodeFiles[index] ? this.backendCodeFiles[index].content : '';
    },
    getCurrentFrontendCode() {
      if (!this.frontendCodeFiles || this.frontendCodeFiles.length === 0) {
        return '';
      }
      const index = parseInt(this.previewFrontend.activeName || '0');
      return this.frontendCodeFiles[index] ? this.frontendCodeFiles[index].content : '';
    },
    getCurrentSqlCode() {
      if (!this.sqlFiles || this.sqlFiles.length === 0) {
        return '';
      }
      const index = parseInt(this.previewSql.activeName || '0');
      return this.sqlFiles[index] ? this.sqlFiles[index].content : '';
    }
  },
  created() {
    const tableId = this.$route.params && this.$route.params.tableId;
    if (tableId) {
      // 获取表详细信息
      getGenTable(tableId).then(res => {
        this.columns = res.data.rows;
        this.info = res.data.info;
        
        // 只有在真正为空或无效时才设置默认路径
        if (!this.info.genPath || this.info.genPath === '/dev-api') {
          // 设置默认路径
          this.fetchWorkspace().then(workspace => {
            if (workspace) {
              this.info.genPath = workspace;
              this.genPath = workspace;
              
              // 同步更新前后端路径，仅当它们也为空或无效时
              if (!this.info.backendGenPath || this.info.backendGenPath === '/dev-api') {
                this.info.backendGenPath = workspace;
                this.backendGenPath = workspace;
              }
              if (!this.info.frontendGenPath || this.info.frontendGenPath === '/dev-api') {
                this.info.frontendGenPath = workspace;
                this.frontendGenPath = workspace;
              }
            }
          });
        } else {
          // 使用数据库中已保存的路径
          this.genPath = this.info.genPath;
        }
        
        // 修复可能错误的API路径，但不覆盖有效值
        if (this.info.backendGenPath === '/dev-api') {
          this.info.backendGenPath = this.info.genPath || '/';
        } else if (!this.info.backendGenPath) {
          this.info.backendGenPath = this.info.genPath;
        }
        
        if (this.info.frontendGenPath === '/dev-api') {
          this.info.frontendGenPath = this.info.genPath || '/';
        } else if (!this.info.frontendGenPath) {
          this.info.frontendGenPath = this.info.genPath;
        }
        
        this.tables = res.data.tables;
      });
      /** 查询字典下拉列表 */
      getDictOptionselect().then(response => {
        this.dictOptions = response.data;
      });
      /** 查询菜单下拉列表 */
      getMenuTreeselect().then(response => {
        this.menus = this.handleTree(response.data, "menuId");
      });
    }
  },
  methods: {
    /** 提交按钮 */
    submitForm(isPromise = false) {
      const genFormRef = this.$refs.genInfo.$refs.genInfoForm;

      // 创建一个Promise对象来处理表单验证和提交
      const formPromise = new Promise((resolve, reject) => {
        // 验证表单
        if (genFormRef) {
          genFormRef.validate(valid => {
            if (valid) {
              // 合并表单数据
              const genTable = Object.assign({}, this.info);
              genTable.columns = this.columns;
              
              // 获取选项参数
              if (this.$refs.genInfo) {
                const options = this.$refs.genInfo.getParams();
                if (options) {
                  genTable.params = options;
                }
              }
              
              // 在前端控制台打印保存的信息
              console.log("保存的生成配置:", genTable);
              
              // 提交表单数据
              updateGenTable(genTable).then(res => {
                this.$modal.msgSuccess(res.msg || "保存成功");
                resolve(true);
              }).catch(err => {
                console.error("保存失败:", err);
                this.$modal.msgError(err.msg || "保存失败");
                reject(err);
              });
            } else {
              this.$modal.msgError("表单校验失败，请检查表单数据");
              reject(new Error("表单校验失败"));
            }
          });
        } else {
          this.$modal.msgError("表单引用不存在");
          reject(new Error("表单引用不存在"));
        }
      });

      // 如果需要返回Promise，则返回
      if (isPromise) {
        return formPromise;
      }
    },
    /** 关闭按钮 */
    close() {
      const obj = { path: "/tool/gen", query: { t: Date.now(), pageNum: this.$route.query.pageNum } };
      this.$tab.closeOpenPage(obj);
    },
    /** 生成代码按钮 */
    handleGenCode() {
      if (!this.tableId) {
        this.$modal.msgError("请先选择要生成代码的表");
        return;
      }
      
      const tableName = this.info.tableName;
      
      // 添加确认对话框
      this.$confirm('确认生成代码？如果代码文件已存在将不会重新生成。注意：SQL菜单文件不会被生成。', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        dangerouslyUseHTMLString: true,
        message: '<div>确认生成代码？<br><ul style="text-align:left;margin-top:10px;padding-left:20px;"><li>如果代码文件已存在将不会重新生成</li><li style="color:#E6A23C;font-weight:bold;">SQL菜单文件(.sql)将不会被生成</li></ul></div>',
        type: 'info'
      }).then(() => {
        // 用户确认，继续生成代码
        this.doGenCode(tableName);
      }).catch(() => {
        // 用户取消，不执行任何操作
      });
    },
    
    /** 执行代码生成 */
    doGenCode(tableName) {
      // 添加合并模式参数
      const params = {
        mergeMode: this.info.mergeMode || "1" // 默认使用智能合并模式
      };
      
      // 获取菜单信息
      if (this.$refs.genInfo) {
        // 从genInfo组件获取参数
        const menuParams = this.$refs.genInfo.getParams();
        
        // 添加上级菜单ID和名称
        if (menuParams.parentMenuId) {
          params.parentMenuId = menuParams.parentMenuId;
        }
        if (menuParams.parentMenuName) {
          params.parentMenuName = menuParams.parentMenuName;
        }
      }
      
      // 如果没有获取到上级菜单信息，设置默认值
      if (!params.parentMenuId) {
        params.parentMenuId = "1"; // 默认系统管理ID
      }
      if (!params.parentMenuName) {
        params.parentMenuName = "系统管理"; // 默认系统管理名称
      }
      
      console.log("生成代码参数:", params);
      
      // 显示生成中提示
      this.$modal.loading("检查文件是否存在...");
      
      // 先检查文件是否存在
      checkFileExists(tableName, params).then(response => {
        this.$modal.closeLoading();
        
        const data = response.data;
        if (data && data.exists) {
          // 文件已存在
          const fileCount = data.fileCount || 0;
          const files = data.files || [];
          
          // 构建提示信息
          let message = `发现${fileCount}个文件已存在，不再重复生成。`;
          
          // 创建一个格式化的文件列表
          if (files.length > 0) {
            this.$notify({
              title: '已存在的文件',
              dangerouslyUseHTMLString: true,
              message: `<div style="max-height: 300px; overflow-y: auto;">
                <p>已存在${fileCount}个文件，不再重复生成：</p>
                <ul style="padding-left: 20px; margin-top: 10px;">
                  ${files.map(file => `<li style="margin-bottom: 5px; word-break: break-all;">${file}</li>`).join('')}
                  ${fileCount > files.length ? `<li>...以及其他 ${fileCount - files.length} 个文件</li>` : ''}
                </ul>
              </div>`,
              duration: 10000,
              type: 'warning'
            });
          } else {
            // 如果没有返回具体文件列表，使用简单提示
            this.$modal.msgInfo(message);
          }
          return;
        }
        
        // 文件不存在，继续生成代码
        this.$modal.loading("正在生成代码...");
        genCode(tableName, params).then(response => {
          this.$modal.closeLoading();
          this.genSuccessful = true;
          this.genResultVisible = true;
        }).catch(err => {
          this.$modal.closeLoading();
          
          // 检查错误消息
          const errorMsg = err.msg || err.message || '';
          
          // 如果是文件已存在的错误
          if (errorMsg.includes("已有") && errorMsg.includes("文件存在") && errorMsg.includes("不再重复生成")) {
            // 这是我们期望的行为，显示提示而不是错误
            this.$modal.msgInfo("代码文件已存在，不再重复生成。" + errorMsg);
            return; // 直接返回，不显示结果对话框
          }
          
          // 其他类型的错误处理
          if (errorMsg.includes("文件存在") || errorMsg.includes("已有") || errorMsg.includes("智能合并") || errorMsg.includes("覆盖")) {
            // 文件已存在的情况，仍然显示为成功，但带有提示信息
            this.genSuccessful = true;
            this.genErrorMsg = errorMsg;
          } else {
            // 其他错误情况
            this.genSuccessful = false;
            this.genErrorMsg = errorMsg || '生成过程中发生错误，请重试或联系管理员';
          }
          
          this.genResultVisible = true;
        });
      }).catch(err => {
        this.$modal.closeLoading();
        this.$modal.msgError("检查文件是否存在时出错：" + (err.msg || err.message || '未知错误'));
      });
    },
    /** 预览代码 */
    handlePreview() {
      if (!this.tableId) {
        this.$modal.msgError("请先选择要预览的表");
        return;
      }
      
      // 确保使用正确的API
      previewTable(this.tableId).then(response => {
        this.preview.open = true;
        this.preview.title = "代码预览";
        const data = response.data;
        
        // 清空之前的数据
        this.backendCodeFiles = [];
        this.frontendCodeFiles = [];
        this.sqlFiles = [];
        
        // 将代码文件分类
        Object.keys(data).forEach((key, index) => {
          const fileName = key.substring(key.lastIndexOf("/") + 1);
          const fileContent = data[key];
          const fileItem = {
            title: fileName,
            content: fileContent,
            key: key,
            index: index.toString()
          };
          
          // 判断文件类型
          if (key.endsWith('.sql.vm') || key.includes('sql.vm') || key.endsWith('.sql')) {
            this.sqlFiles.push(fileItem);
          } else if (key.includes('vue.vm') || key.includes('.js.vm') || key.includes('.html.vm') || key.includes('.css.vm') || key.includes('index.vue.vm')) {
            this.frontendCodeFiles.push(fileItem);
          } else {
            // 默认为后端代码
            this.backendCodeFiles.push(fileItem);
          }
        });
        
        console.log('后端代码文件数量:', this.backendCodeFiles.length);
        console.log('前端代码文件数量:', this.frontendCodeFiles.length);
        console.log('SQL文件数量:', this.sqlFiles.length);
        
        // 设置默认选中的标签页
        if (this.backendCodeFiles.length > 0) {
          this.previewTabType = 'backend';
          this.preview.activeName = '0';
        } else if (this.frontendCodeFiles.length > 0) {
          this.previewTabType = 'frontend';
          this.previewFrontend.activeName = '0';
        } else if (this.sqlFiles.length > 0) {
          this.previewTabType = 'sql';
          this.previewSql.activeName = '0';
        }
        
        // 保存原始数据
        this.preview.data = Object.keys(data).map(key => {
          return {
            title: key.substring(key.lastIndexOf("/") + 1),
            content: data[key]
          };
        });
      }).catch(error => {
        console.error('预览代码失败:', error);
        this.$modal.msgError('获取预览数据失败');
      });
    },
    /** 高亮显示代码 */
    highlightedCode(code, key) {
      if (!code) return '';
      
      let language = 'plaintext';
      
      // 根据文件扩展名判断语言
      if (key.endsWith('.java') || key.includes('.java.vm')) {
        language = 'java';
      } else if (key.endsWith('.xml') || key.includes('.xml.vm')) {
        language = 'xml';
      } else if (key.endsWith('.js') || key.includes('.js.vm')) {
        language = 'javascript';
      } else if (key.endsWith('.vue') || key.includes('.vue.vm')) {
        language = 'html';
      } else if (key.endsWith('.sql') || key.includes('.sql.vm')) {
        language = 'sql';
      } else if (key.endsWith('.html') || key.includes('.html.vm')) {
        language = 'html';
      } else if (key.endsWith('.css') || key.includes('.css.vm')) {
        language = 'css';
      }
      
      try {
        const result = hljs.highlight(language, code, true);
        return result.value || code;
      } catch (e) {
        console.error('高亮代码失败:', e);
        return code;
      }
    },
    /** 复制代码成功 */
    clipboardSuccess() {
      this.$modal.msgSuccess("复制成功");
    },
    
    /** 获取工作空间路径 */
    fetchWorkspace() {
      return new Promise((resolve) => {
        getWorkspace().then(res => {
          if (res.code === 200 && res.data && res.data.workspace) {
            resolve(res.data.workspace);
          } else {
            resolve(null);
          }
        }).catch(() => {
          resolve(null);
        });
      });
    },
    /** 删除生成代码按钮 */
    handleDeleteCode() {
      if (!this.tableId) {
        this.$modal.msgError("请先选择要删除代码的表");
        return;
      }
      
      const tableName = this.info.tableName;
      
      this.$confirm('确认要删除已生成的代码吗？此操作不可逆，请谨慎操作！', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 收集路径参数
        const params = {
          backendPath: this.info.backendGenPath || this.info.genPath,
          frontendPath: this.info.frontendGenPath || this.info.genPath
        };
        
        // 显示删除中提示
        this.$modal.loading("正在删除代码...");
        
        deleteCode(tableName, params).then(response => {
          this.$modal.closeLoading();
          this.$modal.msgSuccess("代码文件删除成功");
        }).catch(err => {
          this.$modal.closeLoading();
          this.$modal.msgError("删除失败：" + (err.msg || err.message || '未知错误'));
        });
      }).catch(() => {
        // 用户取消删除操作
      });
    },
    
    /** 处理下拉菜单的删除命令 */
    handleDeleteCommand(command) {
      if (!this.tableId) {
        this.$modal.msgError("请先选择要删除代码的表");
        return;
      }
      
      const tableName = this.info.tableName;
      let actionText = '';
      
      if (command === 'frontend') {
        actionText = '前端';
      } else if (command === 'backend') {
        actionText = '后端';
      } else {
        return;
      }
      
      this.$confirm(`确认要删除已生成的${actionText}代码吗？此操作不可逆，请谨慎操作！`, '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 收集路径参数
        const params = {
          backendPath: this.info.backendGenPath || this.info.genPath,
          frontendPath: this.info.frontendGenPath || this.info.genPath
        };
        
        // 显示删除中提示
        this.$modal.loading(`正在删除${actionText}代码...`);
        
        // 根据命令选择对应的删除函数
        const deleteFunction = command === 'frontend' ? deleteFrontendCode : deleteBackendCode;
        
        deleteFunction(tableName, params).then(response => {
          this.$modal.closeLoading();
          this.$modal.msgSuccess(`${actionText}代码文件删除成功`);
        }).catch(err => {
          this.$modal.closeLoading();
          this.$modal.msgError(`删除${actionText}代码失败：` + (err.msg || err.message || '未知错误'));
        });
      }).catch(() => {
        // 用户取消删除操作
      });
    },
    handlePreviewData(data) {
      console.log("接收到预览数据事件", data);
      
      if (!data || !data.data) {
        console.error("预览数据格式错误", data);
        this.$modal.msgError("预览数据格式错误");
        return;
      }
      
      const previewData = data.data;
      console.log("处理预览数据", previewData);
      
      // 清空之前的数据
      this.backendCodeFiles = [];
      this.frontendCodeFiles = [];
      this.sqlFiles = [];
      
      // 将代码文件分类
      Object.keys(previewData).forEach((key, index) => {
        const fileName = key.substring(key.lastIndexOf("/") + 1);
        const fileContent = previewData[key];
        const fileItem = {
          title: key.includes('/') ? fileName : key, // 使用自定义名称或文件名
          content: fileContent,
          key: key,
          index: index.toString()
        };
        
        // 判断文件类型
        if (key.endsWith('.sql.vm') || key.includes('sql.vm') || key.endsWith('.sql') || 
            key.includes('SQL') || key.includes('菜单SQL') || key.includes('sql-delete.vm')) {
          this.sqlFiles.push(fileItem);
        } else if (key.includes('vue.vm') || key.includes('.js.vm') || key.includes('.html.vm') || 
                  key.includes('.css.vm') || key.includes('index.vue.vm') || key.includes('/api/')) {
          this.frontendCodeFiles.push(fileItem);
        } else {
          // 默认为后端代码
          this.backendCodeFiles.push(fileItem);
        }
      });
      
      console.log('后端代码文件数量:', this.backendCodeFiles.length);
      console.log('前端代码文件数量:', this.frontendCodeFiles.length);
      console.log('SQL文件数量:', this.sqlFiles.length);
      
      // 设置默认选中的标签页为表结构SQL
      this.previewTabType = 'tableStructure';
      
      if (this.backendCodeFiles.length > 0) {
        this.preview.activeName = '0';
      } 
      if (this.frontendCodeFiles.length > 0) {
        this.previewFrontend.activeName = '0';
      } 
      if (this.sqlFiles.length > 0) {
        this.previewSql.activeName = '0';
      }
      
      // 保存原始数据
      this.preview.data = Object.keys(previewData).map(key => {
        return {
          title: key.includes('/') ? key.substring(key.lastIndexOf("/") + 1) : key,
          content: previewData[key]
        };
      });
      
      // 最后打开预览对话框
      this.preview.open = true;
      this.preview.title = "代码预览";
      
      // 获取表结构SQL
      if (this.info && this.info.tableName) {
        this.tableSqlContent = ""; // 清空之前的内容，显示加载中状态
        this.getTableStructureSql();
      }
    },
    handleClosePreview() {
      this.preview.open = false;
    },
    /** 查看表结构SQL */
    handleViewSql() {
      if (!this.info || !this.info.tableName) {
        this.$modal.msgError("未找到表名信息");
        return;
      }
      
      const tableName = this.info.tableName;
      getTableSql(tableName).then(response => {
        this.tableSqlContent = response.data;
        this.tableSqlVisible = true;
      }).catch(error => {
        console.error('获取表结构SQL失败:', error);
        this.$modal.msgError('获取表结构SQL失败: ' + (error.msg || error.message || '未知错误'));
      });
    },
    
    /** 获取表结构SQL用于预览 */
    getTableStructureSql() {
      if (!this.info || !this.info.tableName) {
        console.error("未找到表名信息");
        return;
      }
      
      const tableName = this.info.tableName;
      getTableSql(tableName).then(response => {
        this.tableSqlContent = response.data;
      }).catch(error => {
        console.error('获取表结构SQL失败:', error);
        this.tableSqlContent = "获取表结构SQL失败: " + (error.msg || error.message || '未知错误');
      });
    }
  },
  mounted() {
    const el = this.$refs.dragTable.$el.querySelectorAll(".el-table__body-wrapper > table > tbody")[0];
    const sortable = Sortable.create(el, {
      handle: ".allowDrag",
      onEnd: evt => {
        const targetRow = this.columns.splice(evt.oldIndex, 1)[0];
        this.columns.splice(evt.newIndex, 0, targetRow);
        for (let index in this.columns) {
          this.columns[index].sort = parseInt(index) + 1;
        }
      }
    });
  }
};
</script>

<style scoped>
/* 表格整体样式 */
.el-table {
  margin-top: 15px;
  border-radius: 4px;
  overflow: hidden;
}

/* 表格边框采用浅色边框线 */
.el-table--border, .el-table--group {
  border: 1px solid #ebeef5;
}

.el-table td, .el-table th.is-leaf {
  border-bottom: 1px solid #ebeef5;
}

/* 表头使用淡灰色背景，字体加粗 */
.el-table th {
  background-color: #f8f8f9 !important;
  color: #606266;
  font-weight: 600;
  height: 45px;
}

/* 页面头部布局 */
.page-header {
  position: relative;
  margin-bottom: 20px;
}

/* 标签页容器 */
.tabs-container {
  width: 100%;
  margin-top: 10px;
}

/* 顶部操作按钮区域 */
.top-action-buttons {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  gap: 10px;
  z-index: 10;
}

/* 预览对话框样式 */
.preview-dialog /deep/ .el-dialog__body {
  padding: 10px 20px;
}

.preview-dialog /deep/ .el-dialog__header {
  padding: 15px 20px;
  background-color: #f8f9fa;
  border-bottom: 1px solid #ebeef5;
}

.preview-dialog /deep/ .el-dialog__title {
  font-weight: 600;
  font-size: 18px;
  color: #303133;
}

.preview-tabs /deep/ .el-tabs__header {
  margin-bottom: 15px;
  background-color: #f8f9fa;
  border-radius: 4px;
  padding: 5px;
}

.preview-tabs /deep/ .el-tabs__item {
  height: 40px;
  line-height: 40px;
  font-size: 15px;
  font-weight: 500;
}

.preview-tabs /deep/ .el-tabs__item.is-active {
  color: #409EFF;
  font-weight: bold;
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding: 10px 0;
  border-bottom: 1px solid #ebeef5;
}

.preview-actions {
  display: flex;
  gap: 10px;
}

/* 文件标签样式 */
.file-tabs {
  display: flex;
  flex-wrap: wrap;
  overflow-x: auto;
  padding-bottom: 5px;
  margin-right: 10px;
  flex: 1;
  max-width: calc(100% - 120px);
}

.file-tab {
  padding: 5px 15px;
  background-color: #f5f7fa;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  margin-right: 5px;
  margin-bottom: 5px;
  cursor: pointer;
  font-size: 13px;
  white-space: nowrap;
  transition: all 0.3s;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.file-tab:hover {
  background-color: #ecf5ff;
  color: #409eff;
}

.file-tab.active {
  background-color: #409eff;
  color: white;
  border-color: #409eff;
}

.preview-content {
  padding: 10px;
  background-color: #fafafa;
  border-radius: 4px;
  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.05);
  overflow: auto;
  max-height: 70vh;
  transition: all 0.3s ease;
}

.code-block {
  margin: 0;
  padding: 15px;
  border-radius: 6px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
  font-size: 14px;
  line-height: 1.5;
  background-color: #fff;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}

.empty-data {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 0;
  color: #909399;
}

.empty-data i {
  font-size: 48px;
  margin-bottom: 10px;
  color: #c0c4cc;
}

.empty-data p {
  font-size: 16px;
}

/* 高亮代码样式增强 */
.hljs {
  background: #f8f9fa;
  color: #383a42;
  padding: 1em;
  border-radius: 5px;
  overflow-x: auto;
  font-size: 14px;
  line-height: 1.6;
}

.hljs-comment,
.hljs-quote {
  color: #a0a1a7;
  font-style: italic;
}

.hljs-doctag,
.hljs-keyword,
.hljs-formula {
  color: #a626a4;
}

.hljs-section,
.hljs-name,
.hljs-selector-tag,
.hljs-deletion,
.hljs-subst {
  color: #e45649;
}

.hljs-literal {
  color: #0184bb;
}

.hljs-string,
.hljs-regexp,
.hljs-addition,
.hljs-attribute,
.hljs-meta-string {
  color: #50a14f;
}

.hljs-built_in,
.hljs-class .hljs-title {
  color: #c18401;
}

.hljs-attr,
.hljs-variable,
.hljs-template-variable,
.hljs-type,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-number {
  color: #986801;
}

.hljs-symbol,
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-title {
  color: #4078f2;
}

.hljs-emphasis {
  font-style: italic;
}

.hljs-strong {
  font-weight: bold;
}

.hljs-link {
  text-decoration: underline;
}

/* 添加标签页样式 */
.custom-tabs /deep/ .el-tabs__item {
  height: 50px;
  line-height: 50px;
  font-size: 16px;
  color: #606266;
  transition: all 0.3s;
  padding: 0 25px;
}

.custom-tabs /deep/ .el-tabs__item.is-active {
  color: #409EFF;
  font-weight: 600;
}

.custom-tabs /deep/ .el-tabs__item:hover {
  color: #409EFF;
  background-color: #f5f7fa;
  border-radius: 4px 4px 0 0;
}

.custom-tabs /deep/ .el-tabs__active-bar {
  height: 3px;
  border-radius: 3px;
}

.custom-tabs /deep/ .el-tabs__nav-wrap::after {
  height: 1px;
  background-color: #e4e7ed;
}

.custom-tabs /deep/ .el-icon-document,
.custom-tabs /deep/ .el-icon-tickets,
.custom-tabs /deep/ .el-icon-setting {
  margin-right: 8px;
  font-size: 20px;
}

/* 自定义标签样式 */
.custom-tab-label {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 5px;
}

.custom-tab-label i {
  margin-right: 8px;
  font-size: 20px;
  background-image: linear-gradient(45deg, #409EFF, #007AFF);
  -webkit-background-clip: text;
  color: transparent;
}

.custom-tab-label span {
  font-size: 16px;
  font-weight: 500;
}

.el-tabs__item.is-active .custom-tab-label i {
  background-image: linear-gradient(45deg, #409EFF, #36D1DC);
  -webkit-background-clip: text;
  color: transparent;
  transform: scale(1.1);
}

.el-tabs__item.is-active .custom-tab-label span {
  background-image: linear-gradient(45deg, #409EFF, #36D1DC);
  -webkit-background-clip: text;
  color: transparent;
  font-weight: 600;
}

.custom-tabs /deep/ .el-tabs__header {
  margin-bottom: 25px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  border-radius: 4px;
  padding: 0 10px;
}

.custom-tabs /deep/ .el-tabs__nav {
  border: none;
}
</style>
